<template>
  <div class="first-bar">
    <div class="echarts-content">
      <div>3D横向柱体有棱角渐变组件-利用自定义组件图表custom多面都可以渐变-------自定义柱图</div>
      <!-- 文献地址：https://blog.csdn.net/qq_43086723/article/details/131006265 -->
      <div style="cursor: pointer;display: inline-block;background-color: rgba(0,0,0,0.3);" @click="saveimg()">点击下载为图片</div>
      <div id="block4-chart1" class="echarts" style="width: 100%;height: 300px;"></div>
    </div>
  </div>
</template>
<script>
import echarts from 'echarts'
let seriesdata = [
  { name: "销售数量", data: [34, 24, 24, 420,720] },
  { name: "总销售额", data: [6800, 7100, 11000, 120000, 10000] },
  //{ name: "平均销售价格", data: [43, 12, 32, 14, 19] },
  // { name: "销售价格", data: [13, 42, 22, 34, 29] }
]
export default {
  name: "FirstBar",
  data() {
    return {
      chart: null,
    };
  },
  watch: {},
  mounted(){
    this.chart1() // 绘制图形
  },
  methods: {
    chart1() {
      this.chart = this.$echarts.init(document.getElementById("block4-chart1"));
      const offsetX = 20;//使柱子变宽
      const offsetY = 10;//棱形的偏移量,如果是柱子一半则是正棱形
      const primaryColor = "0, 108, 255"
      const primaryColor2 = "52,90,139"
      const primaryColor3 = "81,192,219"
      const rgbColors = [
        ['#FFF5EB', '#FFB56B', '#FF8D1A', '#C46200', '#FFFFFF'], 
        ['#FF8266', '#FF8266', '#FF5733', '#D43030', '#FFFFFF'], 
        ['#E6DBFF', '#7948EA', '#7948EA', '#3B09B0', '#FFFFFF'], 
        ['#E0EFFF', '#61ABFF', '#2A82E4', '#0A3D78', '#FFFFFF']
      ]
      const randomColors = [
        ['#E6FAEE', '#00BAAD', '#29D6C2', '#08968D', '#FFFFFF'], 
        ['#E5F5C4', '#A5D63F', '#A6E322', '#6C990C', '#FFFFFF'], 
        ['#FFF9BF', '#FFC300', '#EDDB3B', '#BA9006', '#FFFFFF'], 
        ['#FAE0FF', '#D651ED', '#DE6BF2', '#AC33C1', '#FFFFFF']
      ]// 四位以后采取随机颜色
      // const isMaxShow = true;
      // 绘制左侧面
      const CubeLeft = this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0,
        },
        buildPath: function (ctx, shape) {
          // 会canvas的应该都能看得懂，shape是从custom传入的
          const xAxisPoint = shape.xAxisPoint;
          // console.log('shape',shape);
          const c0 = [shape.x, shape.y];
          const c1 = [shape.x - offsetX, shape.y - offsetY];
          const c2 = [xAxisPoint[0] - offsetX, xAxisPoint[1] - offsetY];
          const c3 = [xAxisPoint[0], xAxisPoint[1]];
          ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath();
        },
      });
      // 绘制右侧面
      const CubeRight = this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0,
        },
        buildPath: function (ctx, shape) {
          const xAxisPoint = shape.xAxisPoint;
          const c1 = [shape.x, shape.y];
          const c2 = [xAxisPoint[0], xAxisPoint[1]];
          const c3 = [xAxisPoint[0] + offsetX, xAxisPoint[1] - offsetY];
          const c4 = [shape.x + offsetX, shape.y - offsetY];
          ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
        },
      });
      // 绘制顶面
      const CubeTop = this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0,
        },
        buildPath: function (ctx, shape) {
          const c1 = [shape.x, shape.y];
          const c2 = [shape.x + offsetX, shape.y - offsetY]; //右点
          const c3 = [shape.x, shape.y - offsetX];
          const c4 = [shape.x - offsetX, shape.y - offsetY];
          ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
        },
      });
      // 注册三个面图形
      this.$echarts.graphic.registerShape('CubeLeft', CubeLeft);
      this.$echarts.graphic.registerShape('CubeRight', CubeRight);
      this.$echarts.graphic.registerShape('CubeTop', CubeTop);

      const MAX = [120000, 120000, 120000, 120000, 120000, 120000, 100, 100, 100, 100, 100, 100]
      // const VALUE = [10, 20, 30, 40, 30, 20, 10, 30, 40, 30, 20, 10];
      // const VALUE1 = [20, 30, 40, 50, 60, 50, 40, 20, 30, 50, 30, 20];
      // const VALUE2 = [50, 40, 20, 60, 40, 30, 20, 40, 50, 60, 40, 30];
      let offetsdata = []//偏移点x值对称数据
      let arr = []//遍历的多组图形series数据
      let one = {}//一组图形实例,一个实际高度和一个背景高度
      let colorlist = []//收集颜色集
      if (seriesdata.length > 0) {
        offetsdata = this.calc(seriesdata.length)
        seriesdata.map((item, index) => {
          let currentcolor = index < 4 ? rgbColors[index] : this.randomArray(randomColors)//颜色数组
          colorlist.push(currentcolor[1])
          let maxh = {
            // 最大高度
            type: 'custom',
            tooltip: {
              show: false
            },
            renderItem: function (params, api) {
              const location = api.coord([api.value(0), api.value(1)])
              return {
                type: 'group',
                // x: -10,
                position: [offetsdata[index], offsetY],
                children: [
                  {
                    type: 'CubeLeft',
                    shape: {
                      api,
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0])
                    },
                    style: {
                      fill: `rgba(${primaryColor}, .1)`
                    }
                  }, {
                    type: 'CubeRight',
                    shape: {
                      api,
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0])
                    },
                    style: {
                      fill: `rgba(${primaryColor}, .3)`
                    }
                  }, {
                    type: 'CubeTop',
                    shape: {
                      api,
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0])
                    },
                    style: {
                      fill: `rgba(${primaryColor}, .4)`
                    }
                  }
                ]
              }
            },
            data: MAX
          }
          one = {
            type: 'custom',
            name: item.name,
            renderItem: (params, api) => {
              const location = api.coord([api.value(0), api.value(1)]);
              return {
                type: 'group',
                position: [offetsdata[index], offsetY],//柱形位置偏移量,图形是居中对称排,表示 [横向平移的距离, 纵向平移的距离]。右和下为正值。
                children: [{
                  type: 'CubeLeft',
                  shape: {
                    api,
                    xValue: api.value(0),
                    yValue: api.value(1),
                    x: location[0],
                    y: location[1],
                    xAxisPoint: api.coord([api.value(0), 0]),
                  },
                  style: {
                    fill: {
                      type: 'linear',
                      x: 0,
                      y: 0,
                      x2: 0,
                      y2: 1,
                      colorStops: [
                        {
                          offset: 0,
                          // color: `rgba(${primaryColor}, 1)`, // 0% 处的颜色
                          color: `${currentcolor[0]}`
                        },
                        {
                          offset: 1,
                          // color: `rgba(${primaryColor2}, 1)`, // 100% 处的颜色
                          color: `${currentcolor[3]}`
                        },
                      ],
                      globalCoord: false, // 缺省为 false
                    },
                  },
                },
                {
                  type: 'CubeRight',
                  shape: {
                    api,
                    xValue: api.value(0),
                    yValue: api.value(1),
                    x: location[0],
                    y: location[1],
                    xAxisPoint: api.coord([api.value(0), 0]),
                  },
                  style: {
                    fill: {
                      type: 'linear',
                      x: 0,
                      y: 0,
                      x2: 0,
                      y2: 1,
                      colorStops: [
                        {
                          offset: 0,
                          // color: `rgba(${primaryColor2}, 1)`, // 0% 处的颜色
                          color: `${currentcolor[2]}`
                        },
                        {
                          offset: 1,
                          // color: `rgba(${primaryColor3}, 1)`, // 100% 处的颜色,如果rgba-a的值小于1会有白色蒙层
                          color: `${currentcolor[3]}`
                        },
                      ],
                      globalCoord: false, // 缺省为 false
                    },
                  },
                },
                {
                  type: 'CubeTop',
                  shape: {
                    api,
                    xValue: api.value(0),
                    yValue: api.value(1),
                    x: location[0],
                    y: location[1],
                    xAxisPoint: api.coord([api.value(0), 0]),
                  },
                  style: {
                    // fill: `rgba(${primaryColor3},1)`
                    fill: currentcolor[3]
                  },
                },
                ],
              };
            },
            data: item.data,
          }
          arr.push(maxh)
          arr.push(one)
        })
      }
      console.log('arr',arr)
      var option = {
        grid: {
          containLabel: true,
          left: 5,
          right: 5,
          bottom: 10,
          top: '30%',
        },
        title:{
          text:'3D自定义柱状图',
          padding:5,
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'shadow'
          },
          formatter:function(params){
            // console.log('params', params)
            let axisValueLabel = params[0].axisValueLabel
            let str = ''
            if (params && params.length>0){
              params.map((v)=>{
                str += v.marker + ' ' + v.seriesName + '：'+v.data+'<br/>'
              })
            }
            return axisValueLabel +'<br/>'+str
          }
        },
        dataZoom: [
          {
            type: 'inside'
          }
        ],
        color: colorlist,
        legend: {
          data: seriesdata.filter((v)=>v.name),
          textStyle: {
            color: '#939AC4',
            fontSize: 11,
          },
          itemWidth: 10,
          itemHeight: 10,
          icon: "circle",
          left: 10,
          top: 20,
        },
        xAxis: [
          {
            type: 'category',
            data: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
            axisTick: {
              show: true,
            },
            splitLine: {
              show: true,
            },
            axisLine: {
              show: true,
              lineStyle: {
                color: 'rgba(0,0,0,1)'
              },
            },
            axisLabel: {
              show: true,
              fontSize: 12,
              color: 'rgba(123, 129, 166, 1)'
            },
          }
        ],
        yAxis: [
          {
            name: '单位：万元',
            nameTextStyle: {
              fontSize: '10',
              color: 'rgba(123, 129, 166, 1)'
            },
            type: 'value',
            axisTick: {
              show: true,
            },
            axisLine: {
              show: true,
              lineStyle: {
                color: 'rgba(255,255,255,0.1)'
              },
            },
            splitLine: {
              show: true,
            },
            axisLabel: {
              show: true,
              fontSize: 11,
              color: 'rgba(123, 129, 166, 1)'
            },
            // axisLine: {
            //     show: false,
            // },
          },
        ],
        series: arr,
      };

      this.chart.setOption(option);
      window.addEventListener("resize", function () {
        this.chart.resize();
      });
    },
    getLinearGradientBar(seriesdata = [{ name: "销售数量", data: [45, 25, 48, 62, 35] }, { name: "总销售额", data: [23, 12, 52, 14, 9] }, { name: "平均销售价格", data: [43, 12, 32, 14, 19] },], MAX = [100, 100, 100, 100, 100],primaryColor = "0, 108, 255"){
      const offsetX = 20;//使柱子变宽
      const offsetY = 10;//棱形的偏移量,如果是柱子一半则是正棱形
      const rgbColors = [
        ['#FFF5EB', '#FFB56B', '#FF8D1A', '#C46200', '#FFFFFF'],
        ['#FF8266', '#FF8266', '#FF5733', '#D43030', '#FFFFFF'],
        ['#E6DBFF', '#7948EA', '#7948EA', '#3B09B0', '#FFFFFF'],
        ['#E0EFFF', '#61ABFF', '#2A82E4', '#0A3D78', '#FFFFFF']
      ]
      const randomColors = [
        ['#E6FAEE', '#00BAAD', '#29D6C2', '#08968D', '#FFFFFF'],
        ['#E5F5C4', '#A5D63F', '#A6E322', '#6C990C', '#FFFFFF'],
        ['#FFF9BF', '#FFC300', '#EDDB3B', '#BA9006', '#FFFFFF'],
        ['#FAE0FF', '#D651ED', '#DE6BF2', '#AC33C1', '#FFFFFF']
      ]// 四位以后采取随机颜色
      // 绘制左侧面
      const CubeLeft = this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0,
        },
        buildPath: function (ctx, shape) {
          // 会canvas的应该都能看得懂，shape是从custom传入的
          const xAxisPoint = shape.xAxisPoint;
          // console.log('shape',shape);
          const c0 = [shape.x, shape.y];
          const c1 = [shape.x - offsetX, shape.y - offsetY];
          const c2 = [xAxisPoint[0] - offsetX, xAxisPoint[1] - offsetY];
          const c3 = [xAxisPoint[0], xAxisPoint[1]];
          ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath();
        },
      });
      // 绘制右侧面
      const CubeRight = this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0,
        },
        buildPath: function (ctx, shape) {
          const xAxisPoint = shape.xAxisPoint;
          const c1 = [shape.x, shape.y];
          const c2 = [xAxisPoint[0], xAxisPoint[1]];
          const c3 = [xAxisPoint[0] + offsetX, xAxisPoint[1] - offsetY];
          const c4 = [shape.x + offsetX, shape.y - offsetY];
          ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
        },
      });
      // 绘制顶面
      const CubeTop = this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0,
        },
        buildPath: function (ctx, shape) {
          const c1 = [shape.x, shape.y];
          const c2 = [shape.x + offsetX, shape.y - offsetY]; //右点
          const c3 = [shape.x, shape.y - offsetX];
          const c4 = [shape.x - offsetX, shape.y - offsetY];
          ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
        },
      });
      // 注册三个面图形
      this.$echarts.graphic.registerShape('CubeLeft', CubeLeft);
      this.$echarts.graphic.registerShape('CubeRight', CubeRight);
      this.$echarts.graphic.registerShape('CubeTop', CubeTop);
      let offetsdata = []//偏移点x值对称数据
      let arr = []//遍历的多组图形series数据
      let one = {}//一组图形实例,一个实际高度和一个背景高度
      let colorlist = []//收集颜色集
      if (seriesdata.length > 0) {
        offetsdata = this.calc(seriesdata.length)
        seriesdata.map((item, index) => {
          let currentcolor = index < 4 ? rgbColors[index] : this.randomArray(randomColors)//颜色数组
          colorlist.push(currentcolor[1])
          // 背景柱
          let maxh = {
            // 最大高度
            type: 'custom',
            tooltip: {
              show: false
            },
            renderItem: function (params, api) {
              const location = api.coord([api.value(0), api.value(1)])
              return {
                type: 'group',
                // x: -10,
                position: [offetsdata[index], offsetY],
                children: [
                  {
                    type: 'CubeLeft',
                    shape: {
                      api,
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0])
                    },
                    style: {
                      fill: `rgba(${primaryColor}, .1)`
                    }
                  }, {
                    type: 'CubeRight',
                    shape: {
                      api,
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0])
                    },
                    style: {
                      fill: `rgba(${primaryColor}, .3)`
                    }
                  }, {
                    type: 'CubeTop',
                    shape: {
                      api,
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0])
                    },
                    style: {
                      fill: `rgba(${primaryColor}, .4)`
                    }
                  }
                ]
              }
            },
            data: MAX
          }
          one = {
            type: 'custom',
            name: item.name,
            renderItem: (params, api) => {
              const location = api.coord([api.value(0), api.value(1)]);
              return {
                type: 'group',
                position: [offetsdata[index], offsetY],//柱形位置偏移量,图形是居中对称排,表示 [横向平移的距离, 纵向平移的距离]。右和下为正值。
                children: [{
                  type: 'CubeLeft',
                  shape: {
                    api,
                    xValue: api.value(0),
                    yValue: api.value(1),
                    x: location[0],
                    y: location[1],
                    xAxisPoint: api.coord([api.value(0), 0]),
                  },
                  style: {
                    fill: {
                      type: 'linear',
                      x: 0,
                      y: 0,
                      x2: 0,
                      y2: 1,
                      colorStops: [
                        {
                          offset: 0,
                          color: `${currentcolor[0]}`
                        },
                        {
                          offset: 1,
                          color: `${currentcolor[3]}`
                        },
                      ],
                      globalCoord: false, // 缺省为 false
                    },
                  },
                },
                {
                  type: 'CubeRight',
                  shape: {
                    api,
                    xValue: api.value(0),
                    yValue: api.value(1),
                    x: location[0],
                    y: location[1],
                    xAxisPoint: api.coord([api.value(0), 0]),
                  },
                  style: {
                    fill: {
                      type: 'linear',
                      x: 0,
                      y: 0,
                      x2: 0,
                      y2: 1,
                      colorStops: [
                        {
                          offset: 0,
                          // color: `rgba(${primaryColor2}, 1)`, // 0% 处的颜色
                          color: `${currentcolor[2]}`
                        },
                        {
                          offset: 1,
                          // color: `rgba(${primaryColor3}, 1)`, // 100% 处的颜色,如果rgba-a的值小于1会有白色蒙层
                          color: `${currentcolor[3]}`
                        },
                      ],
                      globalCoord: false, // 缺省为 false
                    },
                  },
                },
                {
                  type: 'CubeTop',
                  shape: {
                    api,
                    xValue: api.value(0),
                    yValue: api.value(1),
                    x: location[0],
                    y: location[1],
                    xAxisPoint: api.coord([api.value(0), 0]),
                  },
                  style: {
                    // fill: `rgba(${primaryColor3},1)`
                    fill: currentcolor[3]
                  },
                },
                ],
              };
            },
            data: item.data,
          }
          arr.push(maxh)
          arr.push(one)
        })
      }
      console.log('arr', arr)
      return arr
    },
    /** 随机取数组元素中的值工具 */
    randomArray(array) {
      var length = array.length
      var randomIndex = Math.floor(Math.random() * length)
      return array[randomIndex]
    },
    // 对称数据
    calc(group) {
      const len = Math.floor(group / 2), gap = 40;
      const result = [];
      let index = 0;
      if (group % 2 == 0) {
        let start = -20;
        for (let i = len; i >= 1; i--) {
          result[index++] = start + gap * -(i - 1);
        }
        start = 20;
        for (let i = 1; i <= len; i++) {
          result[index++] = start + gap * (i - 1);
        }
      }
      else {
        let start = 0;
        for (let i = len; i >= 1; i--) {
          result[index++] = start + gap * -i;
        }
        result[index++] = 0;
        start = 0;
        for (let i = 1; i <= len; i++) {
          result[index++] = start + gap * i;
        }
      }
      // console.log('对等数据', result)
      return result
    },
    // 保存为图片下载
    saveimg(){
      // 生成 base64 图片
      const src = this.chart.getDataURL({
        pixelRatio: 2,
        backgroundColor: "#08172A",
      });
      
      // 获取chart配置option对象
      let option = this.chart._api.getOption()
      console.log('this.chart', this.chart._api.getOption())
      // 下载
      const a = document.createElement("a");
      a.href = src;
      a.download = option.title[0].text || "chart-img";
      a.click();
    },

  }
}
</script>
<style lang="scss" scoped="scoped">
</style>